import { expect } from 'chai';
import * as sinon from 'sinon';
import { getParameters, extractParametersFromArtifactContent } from '../src/getParameters';

describe('getParameters', () => {
  let sandbox: sinon.SinonSandbox;

  beforeEach(() => {
    sandbox = sinon.createSandbox();
  });

  afterEach(() => {
    sandbox.restore();
    delete process.env.TEMPLATE_PARAMETERS;
  });

  describe('getParameters', () => {
    it('should return parsed parameters from environment variable', () => {
      process.env.TEMPLATE_PARAMETERS = '{"key1": "value1", "key2": "value2"}';
      
      const result = getParameters();
      
      expect(result).to.be.instanceOf(Map);
      expect(result.get('key1')).to.equal('value1');
      expect(result.get('key2')).to.equal('value2');
    });

    it('should return empty map when TEMPLATE_PARAMETERS is not set', () => {
      delete process.env.TEMPLATE_PARAMETERS;
      
      const result = getParameters();
      
      expect(result).to.be.instanceOf(Map);
      expect(result.size).to.equal(0);
    });

    it('should handle empty string in TEMPLATE_PARAMETERS', () => {
      process.env.TEMPLATE_PARAMETERS = '';
      
      const result = getParameters();
      
      expect(result).to.be.instanceOf(Map);
      expect(result.size).to.equal(0);
    });

    it('should handle base64 encoded parameters', () => {
      const base64Content = Buffer.from('{"key1": "value1"}').toString('base64');
      process.env.TEMPLATE_PARAMETERS = base64Content;
      
      const result = getParameters();
      
      expect(result).to.be.instanceOf(Map);
      expect(result.get('key1')).to.equal('value1');
    });
  });

  describe('extractParametersFromArtifactContent', () => {
    it('should parse JSON string to Map', () => {
      const jsonString = '{"param1": "value1", "param2": "value2"}';
      
      const result = extractParametersFromArtifactContent(jsonString);
      
      expect(result).to.be.instanceOf(Map);
      expect(result.get('param1')).to.equal('value1');
      expect(result.get('param2')).to.equal('value2');
    });

    it('should return empty Map for undefined input', () => {
      const result = extractParametersFromArtifactContent(undefined);
      
      expect(result).to.be.instanceOf(Map);
      expect(result.size).to.equal(0);
    });

    it('should decode base64 string before parsing', () => {
      const originalString = '{"test": "base64"}';
      const base64String = Buffer.from(originalString).toString('base64');
      
      const result = extractParametersFromArtifactContent(base64String);
      
      expect(result.get('test')).to.equal('base64');
    });

    it('should return empty Map for invalid JSON', () => {
      expect(() => extractParametersFromArtifactContent('invalid json')).to.throw();
    });

    it('should filter out custom and upstream values', () => {
      const jsonString = '{"key1": "value1", "key2": "custom", "key3": "upstream", "key4": "value4"}';
      
      const result = extractParametersFromArtifactContent(jsonString);
      
      expect(result).to.be.instanceOf(Map);
      expect(result.get('key1')).to.equal('value1');
      expect(result.get('key2')).to.be.undefined;
      expect(result.get('key3')).to.be.undefined;
      expect(result.get('key4')).to.equal('value4');
      expect(result.size).to.equal(2);
    });

    it('should handle empty string input', () => {
      const result = extractParametersFromArtifactContent('');
      
      expect(result).to.be.instanceOf(Map);
      expect(result.size).to.equal(0);
    });

    it('should handle special characters in parameter values', () => {
      const jsonString = '{"unicode": "测试中文", "emoji": "🚀🎯", "special": "!@#$%^&*()", "spaces": "hello world", "empty": ""}';
      
      const result = extractParametersFromArtifactContent(jsonString);
      
      expect(result).to.be.instanceOf(Map);
      expect(result.get('unicode')).to.equal('测试中文');
      expect(result.get('emoji')).to.equal('🚀🎯');
      expect(result.get('special')).to.equal('!@#$%^&*()');
      expect(result.get('spaces')).to.equal('hello world');
      expect(result.get('empty')).to.equal('');
    });

    it('should handle numeric keys and values', () => {
      const jsonString = '{"123": "numeric-key", "string-key": 456, "789": 101112}';
      
      const result = extractParametersFromArtifactContent(jsonString);
      
      expect(result).to.be.instanceOf(Map);
      expect(result.get('123')).to.equal('numeric-key');
      expect(result.get('string-key')).to.equal(456);
      expect(result.get('789')).to.equal(101112);
    });

    it('should handle malformed base64 string gracefully', () => {
      const malformedBase64 = 'invalid-base64-string!';
      expect(() => extractParametersFromArtifactContent(malformedBase64)).to.throw();
    });

    it('should handle large parameter values', () => {
      const largeValue = 'a'.repeat(1000);
      const jsonString = `{"large": "${largeValue}"}`;
      
      const result = extractParametersFromArtifactContent(jsonString);
      
      expect(result).to.be.instanceOf(Map);
      expect(result.get('large')).to.equal(largeValue);
    });
  });


});